package com.jxpanda.infrastructure.crypto.algorithm.encrypt;

import com.jxpanda.infrastructure.crypto.algorithm.encrypt.contract.AbstractSymmetricEncrypt;
import com.jxpanda.infrastructure.crypto.constant.AlgorithmEncrypt;
import com.jxpanda.infrastructure.crypto.toolkit.IvKit;
import lombok.Getter;

import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

@Getter
public class AesEncrypt extends AbstractSymmetricEncrypt {

    public AesEncrypt(AlgorithmEncrypt.AES aes, SecretKey key) {
        super(aes.getAlgorithm(), key);
    }

    public AesEncrypt(AlgorithmEncrypt.AES aes, SecretKey key, byte[] ivBytes) {
        super(aes.getAlgorithm(), key, ivBytes);
    }

    public AesEncrypt(AlgorithmEncrypt.AES aes, SecretKey key, IvParameterSpec ivParameterSpec) {
        super(aes.getAlgorithm(), key, ivParameterSpec);
    }

    public static AesEncrypt createDefault() {
        return AlgorithmEncrypt.AES.AES_CBC_PKCS5.builder().buildDefault();
    }

    public static Builder builder(AlgorithmEncrypt.AES aes) {
        return new Builder(aes);
    }

    public static class Builder extends AbstractSymmetricEncrypt.Builder<AlgorithmEncrypt.AES, AesEncrypt> {
        protected Builder(AlgorithmEncrypt.AES aes) {
            super(aes);
        }

        @Override
        public AesEncrypt buildDefault() {
            SecretKey key = getKeyOrDefault();
            IvParameterSpec ivParameterSpec = getIvParameterSpecOrDefault(IvKit.generateAesIv());
            return new AesEncrypt(getSymmetricAlgorithm(), key, ivParameterSpec);
        }
    }

}
